package com.juc.lock;

import java.util.concurrent.TimeUnit;

/**
 * synchronized:锁的是什么
 *
 * 1 标准访问有ab两个线程，请问先打印邮件还是短信？ 邮件
 * 2 sendEmail方法暂停3s，请问先打印邮件还是短信？ 邮件
 * 3 新增一个普通的hello方法，请问先打印邮件还是hello？ hello
 * 4 有2部手机(对象锁；this)，请问先打印邮件还是短信？ 短信
 * 5 两个静态同步方法(类锁；phone.class)，同一部手机，请问先打印邮件还是短信？ email
 * 6 两个静态同步方法，2部手机，请问先打印邮件还是短信？email
 * 7 1个静态同步方法(类锁)，1个普通同步方法(对象锁)，同1部手机，请问先打印邮件还是短信？sms ，用的是2把不同的锁
 * 8 1个静态同步方法，1个普通同步方法，2部手机，请问先打印邮件还是短信？sms
 *
 *
 * 1-2：
 *      一个对象里面如果有多个synchronize方法，某一个时刻内，只要有一个线程去调用其中的一个synchronize方法了，其它的线程都只能等待
 *      锁的是当前对象this，被锁定后，其它线程都不能进入到当前对象的其它的synchronize方法
 * 3-4：
 *      加个普通方法后发现和同步锁无关
 *      换成两个对象后，不是同一把锁了
 * 5-8：
 *      对于普通方法，锁的是当前实例对象，通常指this，对象锁（new Phone();）
 *      对于静态同步方法，锁的是当前类的Class对象，如Phone.class唯一的一个模板
 *      对于同步方法块，锁的是synchronize括号内的对象
 */
public class Lock8Demo {

    public static void main(String[] args) {

        Phone phone = new Phone();
        Phone phone1 = new Phone();

        new Thread(() ->{
            phone.sendEmail();
        },"a").start();

        try { TimeUnit.SECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } //和中间暂停没关系，是为了让a在b之前启动

        new Thread(() ->{
            //phone.sendSMS();
            phone1.hello();
        },"b").start();
    }
}


class Phone{

    public synchronized void sendEmail(){
        try { TimeUnit.SECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); }
        System.out.println("-----------sendEmail");
    }

    public synchronized void sendSMS(){
        System.out.println("-----------sendSMS");
    }

    public void hello(){
        System.out.println("----------hello");
    }
}
